package net.cyue.ort.llm.generator;

import net.cyue.ort.llm.ModelAdapter;
import net.cyue.ort.llm.cache.CacheManager;
import net.cyue.ort.llm.sampling.SamplingStrategy;
import net.cyue.ort.llm.util.TokenManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自适应文本生成器
 * 根据配置自动选择采样或Beam搜索生成策略
 */
public class AdaptiveTextGenerator implements TextGenerator {
    private static final Logger logger = LoggerFactory.getLogger(AdaptiveTextGenerator.class);
    
    private final ModelAdapter model;
    private final TokenManager tokenManager;
    private final CacheManager cacheManager;
    private final SamplingStrategy samplingStrategy;
    
    public AdaptiveTextGenerator(
        ModelAdapter model,
        TokenManager tokenManager,
        CacheManager cacheManager,
        SamplingStrategy samplingStrategy
    ) {
        this.model = model;
        this.tokenManager = tokenManager;
        this.cacheManager = cacheManager;
        this.samplingStrategy = samplingStrategy;
    }
    
    
    @Override
    public String generate(String prompt, GenerationConfig config, GenerationCallback callback) {
        long startTime = System.currentTimeMillis();
        
        if (logger.isDebugEnabled()) {
            logger.debug("╔═══════════════════════════════════════════════════════════════╗");
            logger.debug("║          AdaptiveTextGenerator - 开始生成                    ║");
            logger.debug("╚═══════════════════════════════════════════════════════════════╝");
            logger.debug("📝 Prompt (长度: {}): {}", prompt.length(), 
                prompt.length() > 100 ? prompt.substring(0, 100) + "..." : prompt);
            logger.debug("⚙️  配置参数:");
            logger.debug("   • maxNewTokens: {}", config.getMaxNewTokens());
            logger.debug("   • numBeams: {}", config.getNumBeams());
            logger.debug("   • temperature: {}", config.getTemperature());
            logger.debug("   • topK: {}", config.getTopK());
            logger.debug("   • topP: {}", config.getTopP());
            logger.debug("   • doSample: {}", config.isDoSample());
        }
        
        // 根据配置选择生成策略
        String result;
        if (config.getNumBeams() > 1) {
            if (logger.isDebugEnabled()) {
                logger.debug("🎯 选择策略: Beam Search (numBeams={})", config.getNumBeams());
            }
            result = generateWithBeamSearch(prompt, config, callback);
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("🎯 选择策略: Sampling");
            }
            result = generateWithSampling(prompt, config, callback);
        }
        
        long duration = System.currentTimeMillis() - startTime;
        if (logger.isDebugEnabled()) {
            logger.debug("");
            logger.debug("╔═══════════════════════════════════════════════════════════════╗");
            logger.debug("║          AdaptiveTextGenerator - 生成完成                    ║");
            logger.debug("╚═══════════════════════════════════════════════════════════════╝");
            logger.debug("📊 统计信息:");
            logger.debug("   • 总耗时: {}ms ({}s)", duration, String.format("%.2f", duration / 1000.0));
            logger.debug("   • 输出长度: {} 字符", result.length());
        }
        
        return result;
    }
    
    /**
     * 使用采样策略生成
     */
    private String generateWithSampling(String prompt, GenerationConfig config, GenerationCallback callback) {
        if (logger.isDebugEnabled()) {
            logger.debug("创建 SamplingTextGenerator");
        }
        TextGenerator samplingGenerator = new SamplingTextGenerator(
            model,
            tokenManager,
            cacheManager,
            samplingStrategy
        );
        return samplingGenerator.generate(prompt, config, callback);
    }
    
    /**
     * 使用Beam搜索策略生成
     */
    private String generateWithBeamSearch(String prompt, GenerationConfig config, GenerationCallback callback) {
        if (logger.isDebugEnabled()) {
            logger.debug("创建 BeamSearchTextGenerator");
        }
        TextGenerator beamSearchGenerator = new BeamSearchTextGenerator(
            model,
            tokenManager,
            cacheManager,
            samplingStrategy
        );
        return beamSearchGenerator.generate(prompt, config, callback);
    }
}

